<?php

namespace app\data\controller\api\auth;

use app\data\controller\api\Auth;
use app\data\service\BaseUserMessageService;
use app\data\service\CarService;
use app\data\service\ExpressService;
use app\data\service\GoodsService;
use app\data\service\OrderService;
use app\data\service\PaymentService;
use app\data\service\UserAdminService;
use app\data\service\UserBalanceService;
use think\admin\extend\CodeExtend;
use think\exception\HttpResponseException;

/**
 * 用户订单数据接口
 * Class Order
 * @package app\data\controller\api\auth
 */
class Order extends Auth
{
    /**
     * 控制器初始化
     */
    protected function initialize()
    {
        parent::initialize();
        if (empty($this->user['status'])) {
            $this->error('账户已被冻结，不能操作订单数据哦！');
        }
    }

    /**
     * 订单状态统计
     */
    public function total()
    {
//        订单流程状态(0=已取消;2=待付款;6=已完成; 9=待收货)
        $data = ['t0' => 0, 't1' => 0, 't2' => 0, 't3' => 0, 't4' => 0, 't5' => 0, 't6' => 0, 't9' => 0];
        $query = $this->app->db->name('ShopOrder')->where('module', 0)->where(['uuid' => $this->uuid, 'deleted_status' => 0]);
        foreach ($query->field('status,count(1) count')->group('status')->cursor() as $item) {
            $data["t{$item['status']}"] = $item['count'];

            if ($item['status'] == 4 || $item['status'] == 5) {
                if (empty($data["t9"])) {
                    $data["t9"] = $item['count'];
                } else {
                    $data["t9"] = $data["t9"] + $item['count'];
                }
            }

        }
        $this->success('获取订单统计', $data);
    }

    /**
     * 获取订单列表
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function get()
    {
        $status = input('status', '');
        if ($status !== '') {
            if ($status == '4') {
                $map[] = ['status', 'in', [3, 4]];
            } else if ($status == '5') {
                $map[] = ['status', 'in', [5, 6]];
            } else if ($status == '1') {
                $map[] = ['status', 'in', [1, 2, 3, 4]];
            } else {
                $map[] = ['status', '=', $status];
            }

        } else {
            $map[] = ['status', '>', -1];
        }
        $map[] = ['uuid', '=', $this->uuid];

        $result = $this->_query('car_order_review')
            ->where($map)
            ->field('id,status,order_no,plate_number,snapshot,pay_at')
            ->order('pay_at desc, id desc')
            ->page(true, false, false, 20);

        foreach ($result['list'] as &$vo) {
            $snapshot = json_decode($vo['snapshot'], true);
            $vo['vehicle_type'] = $snapshot['car_info']['vehicle_type'] ?? [];
            $vo['status_text'] = OrderService::instance()->orderReviewStatus2Text($vo['status']);
            unset($vo['snapshot']);
        }
        $this->success('获取订单数据成功！', $result);
    }

    /**
     * 订单详情
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function detail()
    {
        [$map, $order] = $this->getOrderData();

        // 关联基础订单
        $carOrderBase = $this->app->db->name('car_order_base')
            ->withoutField('id,order_review_id,uuid,service_provider_uid,car_info_id,order_no,snapshot')
            ->where('order_review_id', $order['id'])
            ->findOrEmpty();

        // 关联加价订单
        $carOrderAdd = $this->app->db->name('car_order_add')
            ->withoutField('id,order_review_id,uuid,service_provider_uid,car_info_id,order_no,snapshot')
            ->where('order_review_id', $order['id'])
            ->findOrEmpty();
        if (!empty($carOrderAdd)) {
            $carOrderAdd['add_info'] = json_decode($carOrderAdd['add_info'], true);
        }

        // 关联司机信息
        $user = [
            'id' => $this->user['id'],
            'phone' => $this->user['phone'],
            'nickname' => $this->user['nickname'],
            'headimg' => $this->user['headimg'],
        ];
        $user = UserAdminService::instance()->formatUserField($user, false);

        // 关联服务商信息
        $serviceProvider = $this->app->db->name('DataUser')
            ->field('id,phone,nickname,headimg')
            ->where('id', $order['service_provider_uid'])
            ->findOrEmpty();
        $serviceProvider = UserAdminService::instance()->formatUserField($serviceProvider, false);

        $order['order_base'] = $carOrderBase ?: null;
        $order['order_add'] = $carOrderAdd ?: null;
        $order['user'] = $user ?: null;
        $order['service_provider'] = $serviceProvider ?: null;
        $order['status_text'] = OrderService::instance()->orderReviewStatus2Text($order['status']);
        $order['order_base_status_text'] = OrderService::instance()->orderBaseStatus2Text($carOrderBase['status'] ?? '');
        $order['order_add_status_text'] = OrderService::instance()->orderAddStatus2Text($carOrderAdd['status'] ?? '');
        $order['snapshot'] = json_decode($order['snapshot'], true);
        if (!empty($order['snapshot']['car_info'])) {
            $order['snapshot']['car_info']['car_conditions'] = explode('、', $order['snapshot']['car_info']['car_conditions']);
            $order['snapshot']['car_info']['appearances'] = json_decode($order['snapshot']['car_info']['appearances'] ?? '', true) ?: [];
        }
        if (empty($order['snapshot']['car_monitoring_station_plan'])) {
            $order['snapshot']['car_monitoring_station_plan'] = $this->app->db->table('car_monitoring_station')->where('id', $order['car_monitoring_station_id_plan'])->findOrEmpty();
        }
        if (is_null($order['plan_offline_at'])) {
            $order['plan_offline_at'] = '';
        }
        if (is_null($order['plan_review_at'])) {
            $order['plan_review_at'] = '';
        }
        if (is_null($order['pay_at'])) {
            $order['pay_at'] = '';
        }

        $this->success('获取订单数据成功！', $order);
    }

    /**
     * @api            {post} data/api/order/calc
     * @apiName        计算价格
     * @apiStatus      working
     * @apiDescription 计算价格-描述
     * @apiPermission  token
     * @apiParam {integer} car_info_id 年审车辆ID
     * @apiParam {string} province 省
     * @apiParam {string} city 市
     * @apiParam {string} area 区
     * @apiParam {integer} car_user_coupon_id 优惠券ID
     * @apiSuccess {object} data
     * @apiSuccess {string} data.total 原价
     * @apiSuccess {string} data.discount 优惠价格
     * @apiSuccess {string} data.price 优惠后价格
     */
    public function calc()
    {
        $data = $this->_vali([
            'car_info_id.require'     => '车辆不能为空',
            'province.require'     => '省不能为空',
            'car_user_coupon_id.default'     => 0,
            'car_monitoring_station_id.require'     => '检测站不能为空',
        ]);

        $result = OrderService::instance()->calc($data['car_info_id'], $data['car_monitoring_station_id'], $data['car_user_coupon_id']);

        $total = $result['total'];
        $discount = $result['discount'];
        $price = $result['price'];

        $result['total'] = $price;
        $result['price'] = $total;
        $this->success('计算价格成功！', $result);
    }

    /**
     * @api            {post} data/api/order
     * @apiName        提交订单
     * @apiStatus      working
     * @apiDescription 提交订单-描述
     * @apiPermission  token
     * @apiParam {integer} car_info_id 年审车辆ID
     * @apiParam {string} province 省
     * @apiParam {string} city 市
     * @apiParam {string} area 区
     * @apiParam {string} hope_review_at 年审日期
     * @apiParam {integer} car_user_coupon_id 优惠券ID
     * @apiParam {integer} car_monitoring_station_id 检测站ID
     * @apiSuccess {object} data
     * @apiSuccess {integer} data.order_no 年审订单号
     * @apiSuccess {integer} data.order_no_base 基础费用订单号
     */
    public function add()
    {
        $data = $this->_vali([
            'car_info_id.require'     => '年审车辆不能为空',
            'province.require'     => '省不能为空',
            'city.require'     => '市不能为空',
            'area.require'     => '区不能为空',
            'hope_review_at.require'     => '年审日期不能为空',
            'car_monitoring_station_id.require'     => '检测站不能为空',
            'car_user_coupon_id.default'     => 0,
        ]);

        // 检查用户状态
        $this->checkUserStatus();

        $carInfo = $this->app->db->name('CarInfos')
            ->where('id', $data['car_info_id'])
            ->where('uuid', $this->uuid)->findOrEmpty();
        if (empty($carInfo)) {
            $this->error('查无该年审车辆');
        }

//        $carMonitoringStationPrices = $this->app->db->name('car_monitoring_station_price')->where('car_monitoring_station_id', $data['car_monitoring_station_id'])->where('vehicle_type', $carInfo['vehicle_type'])->where('status', 0)->select()->toArray();
//        if (!empty($carMonitoringStationPrices)) {
//            $this->error('该检测站暂不支持该车型');
//        }

        // todo 一辆车付款后只能发布一次
//        if ($this->app->db->name('CarOrderReview')->where('car_info_id', $data['car_info_id'])
//            ->where('status', '>', 0)->where('status', '<', 6)->count()) {
//            $this->error('一辆车付款后只能发布一次');
//        }

        // 年审订单数据
        $orderReview['status'] = -1;
        $orderReview['uuid'] = $this->uuid;
        $orderReview['car_info_id'] = $data['car_info_id'];
        $orderReview['order_no'] = CodeExtend::uniqidDate(18, 'R');
        $orderReview['hope_review_at'] = $data['hope_review_at'];
        $orderReview['plan_review_at'] = $data['hope_review_at'];
        $orderReview['plan_offline_at'] = $data['hope_review_at'];
        $orderReview['plate_number'] = $carInfo['plate_number'];
        $orderReview['car_monitoring_station_id_offline'] = $data['car_monitoring_station_id'];
        $orderReview['car_monitoring_station_id_plan'] = $data['car_monitoring_station_id'];

        // 基础订单数据
        $calc = OrderService::instance()->calc($data['car_info_id'], $data['car_monitoring_station_id'], $data['car_user_coupon_id']);
        $orderBase = [
            'status' => 0,
            'uuid' => $this->uuid,
            'car_info_id' => $data['car_info_id'],
            'car_monitoring_station_id' => $data['car_monitoring_station_id'],
            'car_user_coupon_id' => $data['car_user_coupon_id'],
            'order_no' => CodeExtend::uniqidDate(18, 'B'),
            'total' => $calc['total'],
            'discount' => $calc['discount'],
            'price' => $calc['price'],
            'province' => $data['province'],
            'city' => $data['city'],
            'area' => $data['area'],
        ];

        $carMonitoringStation = $this->app->db->table('car_monitoring_station')->where('id', $data['car_monitoring_station_id'])->where('status', 1)->findOrEmpty();
        $carMonitoringStationPrice = $this->app->db->table('car_monitoring_station_price')
            ->where('car_monitoring_station_id', $data['car_monitoring_station_id'])
            ->where('vehicle_type', $carInfo['vehicle_type'])
            ->where('fuel_type', $carInfo['fuel_type'])
            ->findOrEmpty();

        try {
            // 写入订单数据
            $this->app->db->transaction(function () use ($orderReview, $orderBase, $carInfo, $carMonitoringStation, $carMonitoringStationPrice, $data) {

                $orderReview['snapshot'] = json_encode(['car_info' => $carInfo, 'car_monitoring_station_id_plan' => $carMonitoringStation, 'car_monitoring_station_offline' => $carMonitoringStation, 'car_monitoring_station_plan' => $carMonitoringStation,
                    'car_monitoring_station_price' => $carMonitoringStationPrice]);
                $orderReviewId = $this->app->db->name('CarOrderReview')->insertGetId($orderReview);

                $orderBase['order_review_id'] = $orderReviewId;
                $orderBase['snapshot'] = $orderReview['snapshot'];
                $this->app->db->name('CarOrderBase')->insert($orderBase);

                $this->app->db->name('car_user_coupons')->where('id', $data['car_user_coupon_id'])->update([
                    'is_show' => 1,
                ]);
            });

            $response = [
                'order_no' => $orderReview['order_no'],
            ];
            // 返回处理成功数据
            $this->success('下单成功', $response);
        } catch (HttpResponseException $exception) {
            throw $exception;
        } catch (\Exception $exception) {
            $this->error("下单失败，{$exception->getMessage()}");
        }
    }

    /**
     * 获取订单支付参数
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function payment()
    {
        $data = $this->_vali([
            'uuid.value'            => $this->uuid,
            'order_no.require'      => '单号不能为空',
            'type.default'      => 'base',
            'payment_type.default'  => 'wechat_xcx',
            'order_remark.default'  => '',
        ]);

        [$map, $order] = $this->getOrderData();

        if (!in_array($order['status'], [-1, 3])) {
            $this->error('该年审订单状态无需再支付');
        }

        if ($data['type'] == 'base') {
            $orderPay = $this->app->db->name('car_order_base')->where('order_review_id', $order['id'])->find();
        } else {
            $orderPay = $this->app->db->name('car_order_add')->where('order_review_id', $order['id'])->find();
        }
        if (empty($orderPay)) {
            $this->error('查无需要支付的订单');
        }
        if ($orderPay['status'] !== 0) {
            $this->error('该订单状态无法支付');
        }

        $openid = $this->user['openid1'];
        if (empty($openid)) {
            $this->error("发起支付失败, openid不能为空");
        }

        try {
            // 返回订单数据及支付发起参数
            $param = PaymentService::instance('M7629685229982495719')->create($openid, $orderPay['order_no'], $orderPay['price'], '订单支付', '', '', '', $data['type']);
            $this->success('获取支付参数', ['param' => $param]);
        } catch (HttpResponseException $exception) {
            throw $exception;
        } catch (\Exception $exception) {
            $this->error($exception->getMessage());
        }
    }

    /**
     * 【测试使用】模拟支付
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function mock()
    {
        $map = $this->_vali([
            'order_no.require'      => '年审订单号不能为空',
            'type.require'      => '订单类型不能为空',
        ]);

        $orderReview = $this->app->db->name('car_order_review')->where('order_no', $map['order_no'])->findOrEmpty();
        if (empty($orderReview)) {
            $this->error('查无该年审订单');
        }

        if (!in_array($orderReview['status'], [-1, 3])) {
            $this->error('该年审订单状态无需再支付');
        }

        if ($map['type'] == 'add') {
            $orderModel = 'car_order_add';
            $order = $this->app->db->name($orderModel)->where('order_review_id', $orderReview['id'])->findOrEmpty();
        } else {
            $orderModel = 'car_order_base';
            $order = $this->app->db->name($orderModel)->where('order_review_id', $orderReview['id'])->findOrEmpty();
        }

        if (empty($order)) {
            $this->error('查无该订单');
        }

        if ($order['status'] > 0) {
            $this->error('该订单状态无需再支付');
        }

        // 写入订单数据
        $this->app->db->transaction(function () use ($orderModel, $order, $orderReview) {

            $payAt = date('Y-m-d H:i:s');

            $this->app->db->name($orderModel)->where('id', $order['id'])->update([
                'status'          => 1,
                'pay_at' => $payAt,
            ]);

            if ($orderModel == 'car_order_base') {
                $this->app->db->name('car_order_review')->where('id', $orderReview['id'])->update([
                    'status'          => 0,
                    'pay_at' => $payAt,
                ]);
            } else {
                $this->app->db->name('car_order_review')->where('id', $orderReview['id'])->update([
                    'pay_at' => $payAt,
                ]);
            }
        });

        $this->success('模拟支付成功');
    }

    /**
     * 确认年审结束
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function confirm()
    {
        [$map, $order] = $this->getOrderData();

        if ($order['status'] !== 5) {
            $this->error('该订单无法执行[确认年审结束]操作');
        }

        $result = $this->app->db->name('car_order_review')->where('id', $order['id'])->update([
            'status' => 6,
            'confirm_at' => date('Y-m-d H:i:s'),
            'update_at' => date('Y-m-d H:i:s'),
        ]);

        if (!$result) {
            $this->error('确认年审结束失败');
        }

        // 消息通知
        $message = [
            '确认完成',
            $order['plate_number'],
            date('Y-m-d H:i:s'),
            "【年审确认完成】订单{$order['order_no']}的年审流程用户已确认完成，请注意查看"
        ];
        BaseUserMessageService::instance()->sendMessage($order['uuid'], '确认完成', $message);

        $snapshot = json_decode($order['snapshot'], true);
        $reviewPrice = $snapshot['car_monitoring_station_price']['review_price'];
        if (!empty($reviewPrice)) {
            $data['name'] = '检测站费用';
            UserBalanceService::instance()->operatorBalance($order['service_provider_uid'], 'system', $reviewPrice, $data);
        }

        $this->success('确认年审结束成功');
    }


    // ==============================================================================================================

    /**
     * 获取输入订单
     * @return array [map, order]
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function getOrderData(): array
    {
        $map = $this->_vali(['uuid.value' => $this->uuid, 'order_no.require' => '订单号不能为空']);
        $order = $this->app->db->name('CarOrderReview')->where($map)->find();
        if (empty($order)) $this->error('读取订单失败');
        return [$map, $order];
    }




}